home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
sound
/
vdigit.zip
/
VRMOD.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-06-24
|
17KB
|
731 lines
page 58,132
.286c
.MODEL LARGE
;**********************************************************************
;* *
;* Equates *
;* *
;**********************************************************************
tccount equ 72 ;reload count to produce 16572 Hz
countmax_18hz equ 910 ;ratio of new timer rate to old rate
tcaddrc equ 43h ;timer/counter control register address
tcaddrd equ 40h ;timer/counter data register zero
tcmode equ 34h ;mode control byte for timer/counter
ppiaddr equ 61h ;programmable peripheral interface address
;**********************************************************************
;* *
;* Macros *
;* *
;**********************************************************************
ljz macro dest
local skip
jnz skip
jmp dest
skip:
endm
;**********************************************************************
;* *
;* Global variables *
;* *
;**********************************************************************
.DATA
even ;don't put these on an odd boundary
blockaddr dd 0 ;beginning of memory block
blocksize dd 0 ;size of memory block
blockend dd 0 ;last address of memory block + 1
currentaddr dd 0 ;pointer to current record position in memory
datacount dd 0 ;number of data bytes already recorded
fwrtaddr dd 0 ;address of next byte to be written to disk
fwrtcount dd 0 ;number of bytes already written to disk
goflag dw 0 ;indicates whether recording is in progress
fileflag dw 0 ;indicates whether data is written to a file
filehandle dw 0 ;handle of file to receive voice data
hookedflag dw 0 ;indicates whether the interrupt is hooked
countfor_18hz dw 0 ;counter to determine when to call BIOS
comaddr dw 0 ;the address of the COM port
comlist dw 3FEh ;needed addresses of all COM ports
dw 2FEh
dw 3EEh
dw 2EEh
shiftcount db 0 ;current bit position within byte
;**********************************************************************
;* *
;* Code *
;* *
;**********************************************************************
.CODE
bios_timer_routine dd 0 ;we keep this in the code segment
; for access through the CS register
; since the other segment registers
; will contain unknown values when
; this is needed
assume ds:DGROUP
;**********************************************************************
;* Speed up the timer tick and set "goflag" *
;**********************************************************************
startvoice proc near
pushf
cli
mov al,tcmode
out tcaddrc,al
mov ax,tccount
out tcaddrd,al
mov al,ah
out tcaddrd,al
mov shiftcount,0
mov countfor_18hz,countmax_18hz
mov goflag,1
popf
ret
startvoice endp
;**********************************************************************
;* Slow the timer tick to normal and clear "goflag" *
;**********************************************************************
stopvoice proc near
pushf
cli
mov al,tcmode
out tcaddrc,al
mov al,0
out tcaddrd,al
out tcaddrd,al
mov goflag,0
popf
ret
stopvoice endp
;**********************************************************************
;* Interrupt service routine *
;**********************************************************************
timer_tick proc far
push ds
push bx
push es
push ax
push cx
push dx
mov ax,DGROUP
mov ds,ax
cmp goflag,0
je chain_exit
les bx,currentaddr
mov ah,es:[bx]
mov dx,comaddr
in al,dx
rcl al,4
rcl ah,1
mov es:[bx],ah
inc shiftcount
and shiftcount,07h
jnz exit_decide
mov ax,es
inc bx
jnz check_wrap
add ax,1000h
check_wrap:
cmp bx,word ptr blockend
jne save_cur_addr
cmp ax,word ptr blockend+2
jne save_cur_addr
mov bx,word ptr blockaddr
mov ax,word ptr blockaddr+2
save_cur_addr:
mov word ptr currentaddr,bx
mov word ptr currentaddr+2,ax
add word ptr datacount,1
adc word ptr datacount+2,0
exit_decide:
dec countfor_18hz
jnz nochain_exit
mov countfor_18hz,countmax_18hz
chain_exit:
pop dx
pop cx
pop ax
pop es
pop bx
pop ds
jmp cs:bios_timer_routine
nochain_exit:
mov al,20h
out 20h,al
pop dx
pop cx
pop ax
pop es
pop bx
pop ds
iret
timer_tick endp
;**********************************************************************
;* Initialization procedure *
;**********************************************************************
;This routine should be called exactly one time before any of the other
; routines in this package are called. It takes no parameters, but returns
; a value indicating success or failure as follows:
;Return value Meaning
;------------ -------
; 0 success
; 1 voice package already initialized
; 2 wrong CPU, won't run on 8088 or 8086
public RVOICE_INIT
RVOICE_INIT proc far
push sp
pop ax
cmp ax,sp
je vi_test
mov ax,2
ret
vi_test:
cmp hookedflag,0
je vi_hook
mov ax,1
ret
vi_hook:
enter 0,0
push si
push di
push ds
lea dx,RVOICE_CBREAK
mov ax,seg RVOICE_CBREAK
mov ds,ax
mov ax,2523h
int 21h
pop ds
push ds
mov ax,3508h
int 21h
mov word ptr cs:bios_timer_routine,bx
mov word ptr cs:bios_timer_routine+2,es
lea dx,timer_tick
mov ax,seg timer_tick
mov ds,ax
mov ax,2508h
int 21h
pop ds
pop di
pop si
mov hookedflag,1
sub ax,ax
leave
ret
RVOICE_INIT endp
;**********************************************************************
;* Cleanup procedure *
;**********************************************************************
;This will restore the interrupt 8 vector to its original state. This
; routine MUST be called before the main program exits to DOS, unless:
; (a) the program has never called RVOICE_INIT, or (b) the program is
; becoming memory-resident.
;There are no parameters. The return values are 0 for success or 1 if
; the interrupt vector was not in fact hooked.
public RVOICE_CLEANUP
RVOICE_CLEANUP proc far
cmp hookedflag,1
je vc_unhook
mov ax,1
ret
vc_unhook:
enter 0,0
push si
push di
call stopvoice
push ds
lds dx,cs:bios_timer_routine
mov ax,2508h
int 21h
pop ds
pop di
pop si
mov hookedflag,0
sub ax,ax
leave
ret
RVOICE_CLEANUP endp
;**********************************************************************
;* Vector restore for Control-Break *
;**********************************************************************
public RVOICE_CBREAK
RVOICE_CBREAK proc far
pusha
push ds
push es
mov ax,DGROUP
mov ds,ax
call stopvoice
call RVOICE_CLEANUP
pop es
pop ds
popa
stc
ret
RVOICE_CBREAK endp
;**********************************************************************
;* "File write catch-up" procedure *
;**********************************************************************
;This must be called frequently from the main program if file writing is
; being used and the length of the data to be recorded is longer than the
; length of the memory block. The routine checks the progress of the
; address pointer in use by the interrupt service routine